package com.novunda.platform.web;

import com.novunda.platform.common.exception.NovException;
import com.novunda.platform.common.reponse.CommonResponse;
import com.novunda.platform.common.reponse.QrCodeStatusResponse;
import com.novunda.platform.common.utils.GsonUtils;
import com.novunda.platform.common.utils.StringUtil;
import com.novunda.platform.common.utils.UserUtils;
import com.novunda.platform.common.web.controller.BaseController;
import com.novunda.platform.entities.User;
import com.novunda.platform.enums.ValidateExceptionEnum;
import com.novunda.platform.security.LoginException;
import com.novunda.platform.services.CenterService;
import com.novunda.platform.services.UserService;
import com.novunda.tca.tdk.domain.ApplyQrCodeResponse;
import com.novunda.tca.tdk.domain.DeviceInfo;
import com.novunda.tca.tdk.domain.ResourceDataInfo;
import com.novunda.tca.tdk.http.OltuURLConnectionClient;
import com.novunda.tca.tdk.utils.ConfigResource;
import org.apache.oltu.oauth2.client.OAuthClient;
import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
import org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse;
import org.apache.oltu.oauth2.client.response.OAuthResourceResponse;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.types.GrantType;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.regex.Pattern;

/**
 * .. 个人中心
 *
 * @author yangg
 * @since 2016/9/9.
 */

@Controller
@RequestMapping("/sys/my")
public class CenterController extends BaseController {

    @Autowired
    private CenterService centerService;
    @Autowired
    private UserService userService;

    private static final Pattern COMPILE1 = Pattern.compile(":::");

    protected String getCode(ServletRequest request) {
        String code = "code";
        return WebUtils.getCleanParam(request, code);
    }

    /**
     * 从请求内获取TCA响应返回数据信息
     *
     * @param request 请求
     * @return TCA返回数据信息
     */
    private ResourceDataInfo getResources(HttpServletRequest request) {

        ResourceDataInfo resourceDataInfo;
        try {

            OAuthClient oAuthClient = new OAuthClient(new OltuURLConnectionClient());

            OAuthClientRequest accessTokenRequest = OAuthClientRequest.tokenLocation(ConfigResource.accessURI)
                    .setGrantType(GrantType.AUTHORIZATION_CODE).setClientId(ConfigResource.clientId)
                    .setClientSecret(ConfigResource.clientSecret).setCode(request.getParameter("code"))
                    .setRedirectURI(ConfigResource.webRedirectUrl).buildQueryMessage();
            OAuthJSONAccessTokenResponse oAuthResponse = oAuthClient.accessToken(accessTokenRequest, "POST");
            String accessToken = oAuthResponse.getAccessToken();
            OAuthClientRequest userInfoRequest = OAuthClientRequest.tokenLocation(ConfigResource.resourceURI)
                    .setParameter("client_id", ConfigResource.clientId).setParameter("access_token", accessToken)
                    .buildQueryMessage();
            OAuthResourceResponse resourceResponse = oAuthClient.resource(userInfoRequest, "GET",
                    OAuthResourceResponse.class);
            String content = resourceResponse.getBody();
            resourceDataInfo = com.novunda.tca.tdk.utils.GsonUtils.getInstance().fromJson(content,
                    ResourceDataInfo.class);

        } catch (OAuthSystemException | OAuthProblemException e) {
            throw new LoginException("资源获取失败", e);
        }

        return resourceDataInfo;
    }

    /**
     * 个人中心首页 -- 请求二维码，到页面显示二维码信息
     *
     * @param model 提示
     * @return 页面
     */
    @RequiresPermissions("sys:devices:add")
    @RequestMapping({"index", ""})
    public String index(Model model) {
        String message;
        try {
            ApplyQrCodeResponse qrCodeResponse = centerService.qrCode(UserUtils.getUser().getLoginName());
            String qrUrl = qrCodeResponse.getQrurl();
            String tempData = qrCodeResponse.getStatusToken();
            model.addAttribute("qrUrl", qrUrl);
            model.addAttribute("code", tempData);
            return "modules/sys/accountInfoForm";

        } catch (NovException e) {
            message = e.getMessage();
        } catch (Exception e) {
            message = "调用失败，请检查TCA是否正常工作";
        }
        model.addAttribute("message", message);
        return "errors/message";

    }

    /**
     * 获取帐号下绑定的设备信息
     *
     * @param model 提示区域
     * @return 页面
     */
    @RequiresPermissions("sys:devices:view")
    @RequestMapping("devices")
    public String devices(Model model) {
        String message;
        try {
            User user = UserUtils.getUser();
            List<DeviceInfo> devices = centerService.devices(user.getLoginName());
            model.addAttribute("devices", devices);
            return "modules/sys/accountInfoList";
        } catch (NovException e) {
            message = e.getMessage();
        } catch (Exception e) {
            message = "调用失败，请检查TCA是否正常工作";
        }
        model.addAttribute("message", message);
        return "errors/message";
    }

    /**
     * 绑定回调
     *
     * @param request  请求
     * @param response 响应
     * @param model    提示块
     * @return 绑定结果
     */
    @RequestMapping("binBack")
    @ResponseBody
    public CommonResponse bindBack(HttpServletRequest request, HttpServletResponse response, Model model) {

        CommonResponse commonResponse = new CommonResponse();
        try {

            ResourceDataInfo resourceDataInfo = getResources(request);

            if (resourceDataInfo == null || resourceDataInfo.getReturnCode() != 0) {
                throw new NovException(ValidateExceptionEnum.INVALID_RESORCE_NULL);
            }

            String qrData = resourceDataInfo.getQrdata();

            if (StringUtil.isEmpty(qrData) || COMPILE1.split(qrData).length <= 0
                    || StringUtil.isEmpty(COMPILE1.split(qrData)[0])) {
                throw new NovException(ValidateExceptionEnum.INVALID_RESORCE_NULL);
            }
            // 获取用户信息
            User user = userService.findByLoginName(COMPILE1.split(qrData)[0]);
            if (user == null) {
                throw new NovException("用户不存在");
            }
            userService.updateStatus(1, user.getId());

            commonResponse.setReturnCode(0);
            commonResponse.setReturnMessage("ok");
        } catch (NovException e) {
            commonResponse.setReturnCode(-1);
            commonResponse.setReturnMessage(e.getMessage());
        } catch (Exception e) {
            LOG.warn(e.getMessage(), e);
            commonResponse.setReturnCode(-1);
            commonResponse.setReturnMessage("error");
        }

        return commonResponse;

    }

    /**
     * 获取二维码状态
     *
     * @param scode 二维码code
     * @return 二维码扫描状态
     */
    @RequestMapping("status")
    @ResponseBody
    public String status(String scode) {
        QrCodeStatusResponse statusResponse;
        try {
            statusResponse = centerService.qrStatus(scode);
        } catch (NovException e) {
            statusResponse = new QrCodeStatusResponse();
            statusResponse.setReturnCode(-1);
            statusResponse.setReturnMessage(e.getMessage());
        } catch (Exception e) {
            LOG.error("获取二维码状态失败", e);
            statusResponse = new QrCodeStatusResponse();
            statusResponse.setReturnCode(-1);
            statusResponse.setReturnMessage("inner error");
        }

        return GsonUtils.getInstance().toJson(statusResponse);

    }

    /**
     * 解除绑定
     *
     * @param deviceId 设备ID
     * @return 页面
     */
    @RequiresPermissions("sys:devices:delete")
    @RequestMapping("release")
    public String release(String deviceId, Model model) {

        centerService.release(deviceId);
        List<DeviceInfo> devices = centerService.devices(UserUtils.getUser().getLoginName());
        model.addAttribute("devices", devices);
        return "redirect:" + "/sys/my/devices";
    }

}
